package org.compiere.dsr;

/**
 * @author E.Maimanov
 * 
 * This class generates 2-dimension array-report from BPM_Form Settings
 */

import java.math.BigDecimal;
import java.util.ArrayList;
import org.adempiere.exceptions.AdempiereException;
import org.compiere.model.MBPMCategory;
import org.compiere.model.MBPMForm;
import org.compiere.model.MBPMFormCell;
import org.compiere.model.MBPMFormColumn;
import org.compiere.model.MBPMFormLine;
import org.compiere.model.MBPMFormValues;
import org.compiere.util.Env;

public class DSR_DataCollection
{
	@SuppressWarnings("unused")
	private static final long serialVersionUID = 4320055593999100229L;
	
	private ArrayList<DSR_Row> elementData = new ArrayList<DSR_Row>();
	private DSR_Row header;
	private MBPMForm form;
	private int BPM_Project_ID;
	private int BPM_ProjectSub_ID;
	private int AD_Org_ID;
	private int AD_Client_ID;
	public int LevelType = 0;
	
	public DSR_DataCollection(int BPM_Form_ID, int BPM_Project_ID, int AD_Org_ID, int AD_Client_ID) 
	{
		form = new MBPMForm(Env.getCtx(), BPM_Form_ID, null);
		this.BPM_Project_ID = BPM_Project_ID;
		this.AD_Client_ID = AD_Client_ID;
		this.AD_Org_ID = AD_Org_ID;
		
		LevelType = MBPMCategory.maxValue(BPM_Form_ID);
		setHeader();
		setStruct(false);
	}
	
	public DSR_DataCollection(int BPM_Form_ID, int BPM_Project_ID, int AD_Org_ID, int AD_Client_ID, int BPM_ProjectSub_ID) 
	{
		form = new MBPMForm(Env.getCtx(), BPM_Form_ID, null);
		this.BPM_Project_ID = BPM_Project_ID;
		this.AD_Client_ID = AD_Client_ID;
		this.AD_Org_ID = AD_Org_ID;
		this.BPM_ProjectSub_ID = BPM_ProjectSub_ID;
		
		LevelType = MBPMCategory.maxValue(BPM_Form_ID);
		setHeader();
		setStruct(false);
	}
	
	public DSR_DataCollection(int BPM_Form_ID) 
	{
		form = new MBPMForm(Env.getCtx(), BPM_Form_ID, null);
		LevelType = MBPMCategory.maxValue(BPM_Form_ID);
		setStruct(true);
	}
	
	public DSR_Row getHeader()
	{
		return header;
	}
	
	public DSR_Row getRow(int index)
	{
		if(index >= 0 && index < elementData.size())
			return elementData.get(index);
		else
			return null;
	}
	
	public int size()
	{
		return elementData.size();
	}
	
	/**
	 * Get header of current report
	 * Header is a set of column's name
	 * First row in elementData (index = 0)
	 */
	private void setHeader()
	{
		MBPMFormColumn[] columns = MBPMFormColumn.getLineFormCode(Env.getCtx(), form.getBPM_FormCode_ID(), null);
		
		header = new DSR_Row();
		
		DSR_Cell nullCell = new DSR_Cell("", "", null);
		nullCell.setHeader(true);
		nullCell.LevelIndex = MBPMCategory.minValue();
		header.add(nullCell);
		
		for(MBPMFormColumn column : columns)
		{
			DSR_Cell cell = new DSR_Cell(column.getName(), "", null);
			cell.setHeader(true);
			cell.LevelIndex = -1;
			cell.Alignment = 1;
			cell.VerticalAlignment = 1;
			cell.isBold = true;
			cell.Formula=column.getFormula();
			header.add(cell);
		}
	}
	
	/**
	 * Get values for current report
	 * and store them in elementData ArrayList<DSR_Row>()
	 */
	private void setStruct(boolean isStruct)
	{		
		MBPMFormLine[] lines = MBPMForm.getLines(Env.getCtx(), form.get_ID(), null);
		MBPMFormColumn[] columns = MBPMFormColumn.getLineFormCode(Env.getCtx(), form.getBPM_FormCode_ID(), null);
		MBPMFormCell cellBP = null;
		
		for(MBPMFormLine row : lines)
		{
			DSR_Row dsrRow = new DSR_Row();

			DSR_Cell rowCell = new DSR_Cell("", row.getName(), null);
			rowCell.setBPM_FormColumn_ID(0);
			rowCell.setBPM_FormLine_ID(row.get_ID());
			rowCell.LevelIndex = MBPMCategory.value(row.getBPM_Category_ID());
			rowCell.setRow(true);
			
			dsrRow.add(rowCell);
			
			for(MBPMFormColumn column : columns) {
				
				cellBP = MBPMFormCell.getCell(Env.getCtx(), column.get_ID(), row.get_ID(), null);
				if(cellBP == null)
					throw new AdempiereException(String.format("No cell for column {0} and row {1}", column.getName(), row.getName()));

				String value = "";
				if(!isStruct)
					value =	MBPMFormValues.getCellValue(row.get_ID(), column.get_ID(), BPM_Project_ID, AD_Org_ID, AD_Client_ID, BPM_ProjectSub_ID);
				DSR_Cell cell = new DSR_Cell(null, null, value);
				cell.setBPM_FormColumn_ID(column.get_ID());
				cell.setBPM_FormLine_ID(row.get_ID());				
				cell.setBPM_FormCell_ID(cellBP.get_ID());
				cell.Alignment = (short) Integer.parseInt(cellBP.getAlignment());
				cell.VerticalAlignment = (short) Integer.parseInt(cellBP.getVerticalAlignment());
				cell.isBold = cellBP.isBold();
				cell.DataType = cellBP.getBPM_DataType();
				if(!isStruct) {
					cell.Formula = cellBP.getFormula();
				} else {
					cell.Formula = column.getFormula();
				}
				dsrRow.add(cell);
			}

			elementData.add(dsrRow);
		}
	}
	
	public String toString()
	{
		int size = this.size();
		int cellSize = 0;
		
		StringBuilder builder = new StringBuilder();
		
		DSR_Row header = this.getHeader();
		
		builder.append(header);
		builder.append("\n");
		
		for(int i = 0; i < size; i++)
		{			
			DSR_Row row = this.getRow(i);
			cellSize = row.size();
			
			for(int j = 0; j < cellSize; j++)
			{
				DSR_Cell cell = row.getCell(j);
				
				String formatValue = String.format("%-20s", cell.getValue());
				
				builder.append(formatValue);
			}
			
			builder.append("\n");
		}
		
		return builder.toString();
	}
}
